package com.boe.hbd.client.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import android.content.Context;

import com.boe.hbd.client.persistence.EntityManager;
import com.boe.hbd.client.persistence.SQLiteAbatis;
import com.boe.hbd.client.service.support.ImageLoaderServiceSupport;
import com.boe.hbd.client.service.support.LandscapeServiceSupport;
import com.boe.hbd.client.service.support.FileBasedConfigurationService;
import com.boe.hbd.client.service.support.GpsBasedLocationService;
import com.boe.hbd.client.service.support.SensorServiceSupport;
import com.boe.hbd.client.service.support.TextToSpeechServiceSupport;
import com.boe.hbd.client.utils.Assert;
import com.boe.hbd.client.Constants;

public class ServiceManager {

	private Context context = null;
	private Map<Class<?>, ManagedService> services = new HashMap<Class<?>, ManagedService>();
	private Properties mProperties = new Properties(); 
	
	private ServiceManager(Context context) {
		try {
			mProperties = new Properties(); 
			mProperties.load(getClass().getResourceAsStream("/configuration.properties"));
		} catch (Throwable e) {
		}
		this.context = context;
		services.put(ImageLoaderService.class, new ImageLoaderServiceSupport());
		services.put(ConfigurationService.class,
				new FileBasedConfigurationService());
		services.put(LocationService.class, new GpsBasedLocationService());
		services.put(LandscapeService.class, new LandscapeServiceSupport());	
		services.put(EntityManager.class, new SQLiteAbatis(context,Constants.BOE_DATABASE_NAME));
		services.put(SensorService.class, new SensorServiceSupport());
		services.put(TextToSpeechService.class,
				new TextToSpeechServiceSupport());
	}

	private static ServiceManager instance = null;

	public static ServiceManager getInstance(Context context) {
		if (instance == null) {
			instance = new ServiceManager(context);
		}
		return instance;
	}

	@SuppressWarnings("unchecked")
	public <T extends ManagedService> T getService(
			Class<? extends T> typeOfService) {
		ManagedService service = services.get(typeOfService);
		Assert.notNull(service,
				"unsupported service:" + typeOfService.getName());
		synchronized (service) {
			if (!service.isInitialized()) {
				service.initialize(context);
			}
		}
		return (T) service;
	}

	public boolean isProductionEnabled() {
		return mProperties.getProperty("productionEnabled","false").equals("true");
	}

	public void pause() {
		for (ManagedService service : services.values()) {
			if (service.isInitialized()) {
				service.pause(context);
			}
		}
	}

	public void resume() {
		for (ManagedService service : services.values()) {
			if (service.isInitialized()) {
				service.resume(context);
			}
		}
	}

	public void destroy() {
		for (ManagedService service : services.values()) {
			if (service.isInitialized()) {
				service.destroy(context);
			}
		}
	}
}
